#include "log_stream.h"

#include <cinttypes>
#include <cstdio>
#include <type_traits>
#include "async_logger.h"
#include "log_format.h"
#include "log_formatter.h"

namespace Base {
namespace SystemLog {
namespace {
constexpr int32_t LOG_HEADER_RESERVE_SIZE = 64;
constexpr int32_t TRUE_STRING_RESERVE_SIZE = 4; // "true"
constexpr int32_t FALSE_STRING_RESERVE_SIZE = 5; // "false"
constexpr const char* NL = "\n";
constexpr size_t NL_LEN = 1;
constexpr const char* COLOR_RESET     = "\033[0m";   // 重置
constexpr size_t COLOR_RESET_LEN      = 4;
constexpr const char* COLOR_TRACE     = "\033[32m";  // 绿色
constexpr size_t COLOR_TRACE_LEN      = 5;
constexpr const char* COLOR_DEBUG     = "\033[36m";  // 青色
constexpr size_t COLOR_DEBUG_LEN      = 5;
constexpr const char* COLOR_INFO      = "\033[0m";  // 默认颜色
constexpr size_t COLOR_INFO_LEN       = 4;
constexpr const char* COLOR_WARN      = "\033[33m";  // 黄色
constexpr size_t COLOR_WARN_LEN       = 5;
constexpr const char* COLOR_ERROR     = "\033[31m";  // 红色
constexpr size_t COLOR_ERROR_LEN      = 5;
constexpr const char* COLOR_FATAL     = "\033[41m";  // 红底白字
constexpr size_t COLOR_FATAL_LEN      = 5;
} // namespace
LogStream::LogStream(LogLevel level, const char* file, int line)
    : level_(level), file_(file), line_(line)
{
    // 预留空间给日志头
    // buffer_.Add(LOG_HEADER_RESERVE_SIZE);
    // 添加颜色头
    if (level == LOG_LEVEL_INFO) {
        buffer_.Append(COLOR_INFO, COLOR_INFO_LEN);
    } else if (level == LOG_LEVEL_DEBUG) {
        buffer_.Append(COLOR_DEBUG, COLOR_DEBUG_LEN);
    } else {
        switch (level) {
            case LOG_LEVEL_TRACE:
                buffer_.Append(COLOR_TRACE, COLOR_TRACE_LEN);
                break;
            case LOG_LEVEL_WARN:
                buffer_.Append(COLOR_WARN, COLOR_WARN_LEN);
                break;
            case LOG_LEVEL_ERROR:
                buffer_.Append(COLOR_ERROR, COLOR_ERROR_LEN);
                break;
            case LOG_LEVEL_FATAL:
                buffer_.Append(COLOR_FATAL, COLOR_FATAL_LEN);
                break;
            case LOG_LEVEL_INFO:
            case LOG_LEVEL_DEBUG:
                break;
            case LOG_LEVEL_COUNT:
            default:
                buffer_.Append(COLOR_RESET, COLOR_RESET_LEN);
                break;
        }
    }
}

LogStream::~LogStream()
{
    Flush();
}

void LogStream::Flush()
{
    // 添加颜色尾
    buffer_.Append(COLOR_RESET, COLOR_RESET_LEN);
    // 添加换行符
    // 2025-10-13优化，不需要自动添加换行符
    // buffer_.Append(NL, NL_LEN);
    if (buffer_.Length() > COLOR_RESET_LEN + COLOR_RESET_LEN) {
        // 获取全局日志器实例并输出
        AsyncLogger<>::GetInstance().Append(buffer_.Data(), buffer_.Length());
    }
    buffer_.Reset();
}

// 布尔类型
LogStream &LogStream::operator<<(bool value)
{
    buffer_.Append(value ? "true" : "false", value ? 4 : 5);
    return *this;
}

// 整数类型格式化
template<typename T>
void LogStream::FormatInteger(T value)
{
    // 使用本地缓冲区避免多次分配
    char buf[32];
    int len = 0;
    
    if constexpr (std::is_signed<T>::value) {
        len = snprintf(buf, sizeof(buf), "%" PRId64, static_cast<int64_t>(value));
    } else {
        len = snprintf(buf, sizeof(buf), "%" PRIu64, static_cast<uint64_t>(value));
    }
    
    if (len > 0) {
        buffer_.Append(buf, static_cast<size_t>(len));
    }
}

LogStream &LogStream::operator<<(short value)
{
    FormatInteger(value);
    return *this;
}

LogStream &LogStream::operator<<(unsigned short value)
{
    FormatInteger(value);
    return *this;
}

LogStream &LogStream::operator<<(int value)
{
    FormatInteger(value);
    return *this;
}

LogStream &LogStream::operator<<(unsigned int value)
{
    FormatInteger(value);
    return *this;
}

LogStream &LogStream::operator<<(long value)
{
    FormatInteger(value);
    return *this;
}

LogStream &LogStream::operator<<(unsigned long value)
{
    FormatInteger(value);
    return *this;
}

LogStream &LogStream::operator<<(long long value)
{
    FormatInteger(value);
    return *this;
}

LogStream &LogStream::operator<<(unsigned long long value)
{
    FormatInteger(value);
    return *this;
}

// 浮点类型
LogStream &LogStream::operator<<(float value)
{
    char buf[32];
    auto len = snprintf(buf, sizeof(buf), "%.6g", value);
    if (len > 0) {
        buffer_.Append(buf, static_cast<size_t>(len));
    }
    return *this;
}

LogStream &LogStream::operator<<(double value)
{
    char buf[32];
    auto len = snprintf(buf, sizeof(buf), "%.12g", value);
    if (len > 0) {
        buffer_.Append(buf, static_cast<size_t>(len));
    }
    return *this;
}

LogStream &LogStream::operator<<(long double value)
{
    char buf[48];
    auto len = snprintf(buf, sizeof(buf), "%.12Lg", value);
    if (len > 0) {
        buffer_.Append(buf, static_cast<size_t>(len));
    }
    return *this;
}

// 字符和字符串
LogStream &LogStream::operator<<(char value)
{
    buffer_.Append(&value, 1);
    return *this;
}

LogStream &LogStream::operator<<(const char* value)
{
    if (value) {
        buffer_.Append(value, strlen(value));
    } else {
        buffer_.Append("(null)", 6);
    }
    return *this;
}

LogStream &LogStream::operator<<(const std::string& value)
{
    buffer_.Append(value.c_str(), value.size());
    return *this;
}

LogStream &LogStream::operator<<(const void* value) {
    char buf[32];
    auto len = snprintf(buf, sizeof(buf), "%p", value);
    if (len > 0) {
        buffer_.Append(buf, static_cast<size_t>(len));
    }
    return *this;
}

LogStream &LogStream::operator<<(const LogFormatter &formatter)
{
    formatter.Format(*this);
    return *this;
}

LogStream &LogStream::operator<<(const LogFormat &format) {
    format.Format(*this);
    return *this;
}
} // namespace SystemLog
} // namespace Base